import socket
import threading
from socketserver import ThreadingTCPServer,StreamRequestHandler
import logging
import datetime

FORMAT = "%(asctime)s %(threadName)s %(thread)d %(message)s"
logging.basicConfig(format=FORMAT, level=logging.INFO)


class ChatServerHandler(StreamRequestHandler):

    clients = {}

    def setup(self):
        super().setup()
        self.event = threading.Event()
        self.lock = threading.Lock()
        with self.lock:
            self.clients[self.client_address] = self.wfile
        #打印每次注册的客户连接
        print(self.clients)

    
    def finish(self):
        super().finish()
        with self.lock:
            self.clients.pop(self.client_address)
        #打印客户端主动退出后注册的客户端连接集
        print(self.clients)
        self.event.set()
    
    def handle(self):
        super().handle()
        while not self.event.is_set():
            try:
                data = self.rfile.read1().strip()
            except Exception as e:
                logging.error(e)
                data = b'quit'
            if data == b'quit' or data == b'':
                break
            msg = "From {}:{}. data={}".format(*self.client_address,data)
            with self.lock:
                for f in self.clients.values():
                    f.write(msg.encode())
                    f.flush()

class ChatServer:
    def __init__(self,ip='127.0.0.1',port=9999):
        self.server = ThreadingTCPServer((ip,port),ChatServerHandler)
        self.server.daemon_threads = True

    def start(self):
        threading.Thread(
            target=self.server.serve_forever, name='chatserver',
            daemon=True
        ).start()

    def stop(self):
        self.server.server_close()


if __name__ == '__main__':
    cs = ChatServer()
    cs.start()



while True:
    cmd = input('>>').strip()
    if cmd == 'quit':
        cs.stop()
        break
    print(threading.enumerate())